# coding:utf-8

from . import api
from flask import request, jsonify, g, current_app
from launch import db
from launch.utils.response_code import RET
from launch.utils.commons import login_required
from launch.models import Order
from launch import constants
from alipay import AliPay
import os
from config import Config


@api.route("/orders/payment", methods=['post'])
@login_required
def order_pay():
    """发起支付宝支付"""

    user_id = g.user_id
    # 获取数据
    re_dict = request.get_json()
    if not re_dict:
        return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")

    order_id = re_dict.get("order_id")
    if not order_id:
        return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")

    try:
        order = Order.query.filter(Order.id == order_id, Order.user_id == user_id,
                                   Order.status == "WAIT_PAYMENT").first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")

    if order is None:
        return jsonify(errno=RET.NODATA, errmsg="订单数据有误")

    # 初始化
    # 获取公私钥字符串
    public_path = os.path.join(Config.BASE_DIR, 'launch/api_1_0/keys/alipay_public_key.pem')
    private_path = os.path.join(Config.BASE_DIR, 'launch/api_1_0/keys/app_private_key.pem')
    app_private_key_string = open(private_path).read()
    alipay_public_key_string = open(public_path).read()
    alipay = AliPay(
        appid=constants.ALIPAY_APP_ID,  # 应用ID,没上线则为沙箱ID
        app_notify_url=None,  # 默认回调url
        app_private_key_string=app_private_key_string,  # 私钥
        alipay_public_key_string=alipay_public_key_string,  # 支付宝公钥
        sign_type="RSA2",  # RSA 或者 RSA2
        debug=True,  # 上线则改为False , 沙箱True
    )
    # 发起支付
    # 调用接口(传参订单号和总价,标题)
    # total_pay = order.total_price + order.transit_price  # Decimal
    order_string = alipay.api_alipay_trade_wap_pay(
        out_trade_no=order_id,  # 订单id
        total_amount=str(order.amount),  # 总金额
        # subject='支付订单:%s' % order_id,
        subject=u'爱家租房%s' % order.id,
        return_url="http://192.168.124.14:5000/payComplete.html",  # 返回的链接地址
        notify_url=None,  # 可选,不填则使用默认notify url
    )

    # 拼接应答地址
    pay_url = constants.ALIPAY_URL_PREFIX + order_string

    # 返回应答
    return jsonify(errno=RET.OK, errmsg="OK", data={"pay_url": pay_url})


@api.route("/orders/payment", methods={'put'})
def save_order_payment_result():
    """
    保存订单支付结果
    :return:
    """
    alipay_dict = request.form.to_dict()
    # 对支付宝的数据进行分离，提取出支付宝的签名参数和剩下的其他数据
    # 取出数据，并删除键值对
    alipay_sign = alipay_dict.pop("sign")
    print("==================================\nresult:", alipay_dict,
          "\n==============================================")
    print("==================================\nalipay_sign:", alipay_sign,
          "\n==============================================")
    # 创建支付宝sdk的工具对象
    # 初始化
    # 获取公私钥字符串
    public_path = os.path.join(Config.BASE_DIR, 'launch/api_1_0/keys/alipay_public_key.pem')
    private_path = os.path.join(Config.BASE_DIR, 'launch/api_1_0/keys/app_private_key.pem')
    app_private_key_string = open(private_path).read()
    alipay_public_key_string = open(public_path).read()
    alipay = AliPay(
        appid=constants.ALIPAY_APP_ID,  # 应用ID,没上线则为沙箱ID
        app_notify_url=None,  # 默认回调url
        app_private_key_string=app_private_key_string,  # 私钥
        alipay_public_key_string=alipay_public_key_string,  # 支付宝公钥
        sign_type="RSA2",  # RSA 或者 RSA2
        debug=True,  # 上线则改为False , 沙箱True
    )

    # 借助工具验证参数的合法性
    # 如果确定参数的支付宝的，返回True，否则返回False
    result = alipay.verify(alipay_dict, alipay_sign)
    print("==================================\nresult:", result, "\n==============================================")
    if result:
        print("enter result")
        # 修改数据库的订单状态信息
        order_id = alipay_dict.get("out_trade_no")
        trade_no = alipay_dict.get("trade_no")  # 支付宝的交易流水号

        try:
            Order.query.filter_by(id=order_id).update({"status": "WAIT_COMMENT", "trade_no": trade_no})
            db.session.commit()
        except Exception as e:
            current_app.logger.error(e)
            db.session.rollback()

    return jsonify(errno=RET.OK, errmsg="OK")
